package elcs.mentoring.model;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import elcs.board.model.ListVO;
import elcs.board.model.PagingBean;
import elcs.member.model.MemberVO;
import elcs.mentoring.exception.AlreadyMentoringException;
import elcs.mentoring.exception.NoMentorException;
import elcs.mentoring.exception.NotEnoughPointException;

@Service
public class MentoringServiceImpl implements MentoringService {
	@Resource(name = "mentoringDaoImpl")
	private MentoringDao mentoringDao;
	@Resource(name = "noteDaoImpl")
	private NoteDao noteDao;

	/**
	 * 자신의 레벨 보다 높은 등급의 레벨을 가져온다. By SSA
	 */
	@Override
	public List getMyMentorLevel(int level) throws Exception {
		return mentoringDao.getMyMentorLevel(level);
	}

	public ListVO questionView(Map map) throws Exception{
		String id=(String)map.get("id");
		List<NoteVO> qlist = (List<NoteVO>) noteDao.getQuestionList(map);
		qlist = settingStatus(qlist, id);
		PagingBean pb=new PagingBean(noteDao.getQuestionNumber(map), (int)map.get("page"));
		ListVO lvo=new ListVO(qlist, pb);
		return lvo;
	}

	@Override
	// 수정
	public Map statusView(Map qMap) throws Exception {
		Map map=new HashMap();
		String id=(String)qMap.get("id");
		ListVO lvo=questionView(qMap);
		map.put("sendRList", new JSONArray(mentoringDao.getSendRequestList(id)));
		map.put("receiveRList", new JSONArray( mentoringDao.getReceiveRequestList(id)));
		map.put("lvo", new JSONObject(lvo));
		return map;
	}


	@Override
	public NoteVO viewNoteContent(int no) throws Exception {
		return noteDao.viewNoteContent(no);
	}
	@Transactional
	@Override
	public void rejectMentorQuestion(int no) throws Exception {
		noteDao.rejectMentorQuestion(no);// 거절
		NoteVO nvo = noteDao.viewNoteContent(no);
		int order = nvo.getRefOrder();
		if (order != 3) {
			if(mentoringDao.getMentorNumberForQuestion(nvo)==0){
				noteDao.rejectDirectQuestion(no);
			}else{
			nvo.setRefOrder(order + 1);
			noteDao.sendOtherMentorQuestion(nvo);}
		}
	}
	@Transactional
	@Override
	public void replyMentorQuestion(NoteVO nvo) throws Exception {
		noteDao.checkReplyQuestion(nvo.getReNoteNo());
		String content=nvo.getContent();
		content = content.replace("\r\n", "<br>");
		content = content.replace("\u0020", "&nbsp;");
		nvo.setContent(content);
		noteDao.replyMentorQuestion(nvo);
	}
	@Transactional
	@Override
	public List getNoteList(Map map) throws Exception {
		noteDao.setReceiveDate(map);	
		return noteDao.getNoteList(map);
	}

	
	@Override
	public void sendNote(NoteVO nvo) throws Exception {
		noteDao.sendNote(nvo);
	}

	@Transactional
	@Override
	public List sendMentorRequest(int no,String id) throws Exception {
		noteDao.updateReject(no);
		if(mentoringDao.checkMentorRelation(no)!=0){
			throw new AlreadyMentoringException("이미 신청된 멘토이거나 멘토관계 입니다.");
		}
		mentoringDao.sendMentorRequest(no);
		return mentoringDao.getSendRequestList(id);
	}
	@Transactional
	@Override
	public List replyReceivedRequest(MentoringVO mentoVO) throws Exception {
		if(mentoVO.getAgree()==1){
			mentoringDao.replyMentorRequest(mentoVO);
		}else if(mentoVO.getAgree()==-1){
			mentoringDao.rejectMentorRequest(mentoVO);
		}
		return  mentoringDao.getReceiveRequestList(mentoVO.getMentor().getId());
	}
	@Transactional
	@Override
	public List cancelRequest(MentoringVO mentoVO) throws Exception {
			mentoringDao.rejectMentorRequest(mentoVO);
		return  mentoringDao.getSendRequestList(mentoVO.getMentee().getId());
	}
	/**
	 *  나의 멘토와 멘티 리스트를 맵으로 묶어 가져온다.
	 */
	@Override
	public Map myMentoringView(String id) throws Exception{
		Map map=new HashMap();
		map.put("mentorList", new JSONArray(mentoringDao.getMyMentorList(id)));
		map.put("menteeList", new JSONArray(mentoringDao.getMyMenteeList(id)));
		return map;
	}


	private List<NoteVO> settingStatus(List<NoteVO> qlist, String id) {
		for (NoteVO nvo : qlist) {
			if (nvo.getSender().getId().equals(id) && nvo.getReNoteNo() != -1) {
				nvo.setStatus("보낸답변");
			} else if (nvo.getSender().getId().equals(id)) {// 내가 보낸 질문
				if (nvo.getRefOrder() == 3 && nvo.getReject() == -1) {
					nvo.setStatus("보낸질문(거절됨)");
				} else if (nvo.getReject() == 1) {
					nvo.setStatus("보낸질문(답변완료)");
				} else {
					nvo.setStatus("보낸질문(대기중)");
				}
			} else if (nvo.getReceiver().getId().equals(id)) {
				if (nvo.getReject() == 0) {
					if (nvo.getReNoteNo() == -1)
						nvo.setStatus("받은질문(대기중)");
					else
						nvo.setStatus("답변");
				} else if (nvo.getReject() == 1) {
					if(nvo.getReNoteNo() == -1)
						nvo.setStatus("받은질문(답변완료)");
					else
						nvo.setStatus("답변");
				} else {
					nvo.setStatus("받은질문(거절함)");
				}
			}
		}
		return qlist;
	}
	/**
	 * 멘토 레벨 선택 시 자신의 레벨과 비교하여 소모되는 포인트를 계산하여 보여준다. By SSA
	 */
	@Override
	public int getPointForRequest(int level, MemberVO mvo) throws Exception {
		Map map=new HashMap();
		map.put("ulevel", level);
		map.put("mylevel", mvo.getLevel());
		map.put("myid", mvo.getId());
		// 레벨에 멘토가 있는지? 멘토관계가 아닌사람 (내 아이디, 멘토레벨)
		// 멘토관계에 속하지 않고 그 해당레벨의 사람의 수를 구한 후 , 0 이면 익셉션 발생
		int mento=mentoringDao.getNumberOfMentor(map);
		if(mento==0){
			throw new NoMentorException("해당 레벨에 속한 멘토가 없습니다.");
		}
		// 선택한 레벨의 해당하는 포인트보다 부족한 경우		
		int point=noteDao.getPointForRequest(map);
		if(point>mvo.getPoint()){
			throw new NotEnoughPointException(point+" 포인트가 부족하여 선택 불가");
		}
		return point;
	}

	/**
	 * 선택한 레벨의 멘토에게 질문 제목과 내용을 전송한다. 레벨 차이만큼 포인트가 감소된다. BY SSA
	 */
	@Transactional
	@Override
	public int sendMentorQuestion(NoteVO nvo) throws Exception {
		Map map=new HashMap();
		map.put("ulevel", nvo.getLevel());
		map.put("mylevel", nvo.getSender().getLevel());
		map.put("myid", nvo.getSender().getId());
		// 레벨에 멘토가 있는지? 멘토관계가 아닌사람 (내 아이디, 멘토레벨)
		// 멘토관계에 속하지 않고 그 해당레벨의 사람의 수를 구한 후 , 0 이면 익셉션 발생
		int mento=mentoringDao.getNumberOfMentor(map);
		if(mento==0){
			throw new NoMentorException("해당 레벨에 속한 멘토가 없습니다.");
		}
		// 선택한 레벨의 해당하는 포인트보다 부족한 경우		
		int point=noteDao.getPointForRequest(map);
		if(point>nvo.getSender().getPoint()){
			throw new NotEnoughPointException(point+" 포인트가 부족하여 전송 불가");
		}
		String content=nvo.getContent();
		content = content.replace("\r\n", "<br>");
		content = content.replace("\u0020", "&nbsp;");
		nvo.setContent(content);
		noteDao.sendMentorQuestion(nvo);
		return point;
	}

	@Override
	public void setReceiveDate(int no) throws Exception {
		noteDao.setReceiveDate(no);

	}

	@Override
	public void deleteNote(NoteVO nvo, String id) throws Exception {
		if (nvo.getSender().getId().equals(id))
			noteDao.senderDeleteNote(nvo.getNo());
		else
			noteDao.receiverDeleteNote(nvo.getNo());

	}
	@Transactional
	@Override
	public NoteVO getContent(int no,String id) throws Exception {
		NoteVO nvo=noteDao.getContent(no);
		if(nvo.getReceiveDate()==null&&nvo.getReceiver().getId().equals(id)){
			noteDao.setReceiveDate(no);
			nvo=noteDao.getContent(no);
		}
		return nvo;
	}
	@Override
	public void senderDeleteNote(int no) throws Exception{
		noteDao.senderDeleteNote(no);
	}
	@Override
	public void receiverDeleteNote(int no) throws Exception{
		noteDao.receiverDeleteNote(no);
	}
	
	@Transactional
	@Override
	public List breakMentorRelationship(MentoringVO mentoVO) throws Exception {
		mentoringDao.rejectMentorRequest(mentoVO);
		return mentoringDao.getMyMentorList(mentoVO.getMentee().getId());
		
	}
	@Transactional
	@Override
	public List breakMenteeRelationship(MentoringVO mentoVO) throws Exception {
		mentoringDao.rejectMentorRequest(mentoVO);
		return mentoringDao.getMyMenteeList(mentoVO.getMentor().getId());
		
	}

	@Override
	public Map CountNewNote(String id) throws Exception {
		HashMap map=new HashMap();
		map.put("newQuestion",noteDao.CountNewQuestion(id));
		map.put("newNote",noteDao.CountNewNote(id));
		return map;
	}

}
